#include "qint32.h"
#include "qdouble.h"

static int dispatchOperation(
	const NumericValue* self, const NumericValue* n, 
	char op, NumericValue* result)
{
	return n->type->int32Operation(n, op, self->int32Val, result);
}

static int int32Operation(
    const NumericValue* self, char op, gint32 n, NumericValue* result)
{
	switch (op)
	{
	case '=' : result->int32Val = n; return 0;
	case '*' : *result = *self; result->int32Val *= n; return 0;
	case '/' : *result = *self; result->int32Val /= n; return 0;
	case '+' : *result = *self; result->int32Val += n; return 0;
	case '-' : *result = *self; result->int32Val -= n; return 0;
	case '%' : *result = *self; result->int32Val %= n; return 0;
	case '|' : *result = *self; result->int32Val |= n; return 0;
	case '&' : *result = *self; result->int32Val &= n; return 0;
	}
	return -1;
}

static int doubleOperation(
	const NumericValue* self, char op, gdouble n, NumericValue* result)
{
	switch (op)
	{
	case '=' : 
		QDouble_init2((QDouble*)result, n); 
		return 0;
	case '*' : 
		QDouble_init2((QDouble*)result, self->int32Val * n);
		return 0;
	case '/' : 
		QDouble_init2((QDouble*)result, self->int32Val / n); 
		return 0;
	case '+' : 
		QDouble_init2((QDouble*)result, self->int32Val + n); 
		return 0;
	case '-' : 
		QDouble_init2((QDouble*)result, self->int32Val - n); 
		return 0;
	case '%' : break;
	case '|' : break;
	case '&' : break;
	}
	return -1;
}

const QInt32Type qint32Type = {
	dispatchOperation, int32Operation, doubleOperation
};

static QInt32 prototype = { &qint32Type.super, 0 };

extern QInt32* QInt32_init(QInt32* self)
{
	*self = prototype;
	return self;
}
